package com.wskj.pay.impl;


import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wskj.common.utils.common.AssertUtils;
import com.wskj.common.utils.ios.IosVerifyUtils;
import com.wskj.pay.IIosService;
import com.wskj.system.service.ISysCommonService;
import com.wskj.workbench.bo.app.AppPayOrderParamBo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author fang
 * @date 2020/2/26
 */
@Slf4j
@AllArgsConstructor
@Service
public class IosServiceImpl implements IIosService {

    private final ISysCommonService iSysCommonService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String iosBeforeRecharge(AppPayOrderParamBo bo) {
       /* Long userId = SecurityUtils.getUserId();
        Long rechargeId = bo.getRechargeId();
        AssertUtils.notNull(rechargeId, "rechargeId不能为空");
        TbRecharge dbTbRecharge = tbRechargeMapper.selectById(rechargeId);
        AssertUtils.notNull(dbTbRecharge, "该充值信息已被删除");
        AssertUtils.isTrue(dbTbRecharge.getStatus() != null && dbTbRecharge.getStatus() == 1, "该充值信息已被停用");
        TbBusiness tbBusiness = new TbBusiness();
        tbBusiness.setUserId(userId);
        tbBusiness.setBusinessType("1");
        tbBusiness.setBusinessNumber(IdWorker.getIdStr());
        tbBusiness.setActualTotal(dbTbRecharge.getRechargeAmount());
        tbBusiness.setRechargeId(dbTbRecharge.getRechargeId());
        tbBusiness.setRechargeValue(dbTbRecharge.getRechargeValue());
        tbBusiness.setRechargeAmount(dbTbRecharge.getRechargeAmount());
        tbBusiness.setProductId(dbTbRecharge.getProductId());
        tbBusiness.setPayStatus(1);
        Date currentDate = new Date();
        tbBusiness.setPayTime(currentDate);
        baseMapper.insert(tbBusiness);*/
        return "";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int iosAfterRecharge(AppPayOrderParamBo bo) {
        /*LambdaUpdateWrapper<TbBusiness> tbBusinessLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        tbBusinessLambdaUpdateWrapper.eq(TbBusiness::getBusinessNumber, bo.getOrderNumber());
        TbBusiness dbTbBusiness = baseMapper.selectOne(tbBusinessLambdaUpdateWrapper);
        AssertUtils.notNull(dbTbBusiness, "该订单已不存在");
        AssertUtils.isFalse(dbTbBusiness.getPayStatus() != null && dbTbBusiness.getPayStatus() == 2, "该订单已支付");
        // 校验收据码
        this.iosInAppPurchase(dbTbBusiness.getProductId(),bo.getReceipt(), dbTbBusiness);
        // 钱包-金币余额新增
        sysUserMapper.increasedGoldBalanceByUserId(dbTbBusiness.getUserId(), dbTbBusiness.getRechargeValue());
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPayStatus, 2);
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPayType, PayTypeEnum.IOS_PAY.getValue());
        Date currentDate = new Date();
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPayTime, currentDate);
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getReceipt,dbTbBusiness.getReceipt());
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getInTradeNo,dbTbBusiness.getInTradeNo());
        int count = baseMapper.update(null, tbBusinessLambdaUpdateWrapper);

        // 充值金币进入钱包金币余额
        TbTrade tbTrade_1 = new TbTrade();
        tbTrade_1.setBusinessId(dbTbBusiness.getBusinessId());
        tbTrade_1.setTradeUserId(dbTbBusiness.getUserId());
        tbTrade_1.setTradeType(TradeTypeEnum.RECHARGE_GOLD_IN.getValue());
        tbTrade_1.setTradeAmount(dbTbBusiness.getRechargeValue());
        tbTrade_1.setTradeTime(currentDate);
        tbTradeMapper.insert(tbTrade_1);
        // 推送消息
        SysNotice sysNotice = new SysNotice();
        sysNotice.setNoticeType("2");
        String noticeTitle = NoticeTypeClassifyEnum.RECHARGE_GOLD.getDesc();
        sysNotice.setNoticeTitle(noticeTitle);
        String noticeContent = String.format(NoticeTypeClassifyEnum.RECHARGE_GOLD.getContent());
        sysNotice.setNoticeContent(noticeContent);
        sysNotice.setStatus("1");
        sysNotice.setObjCode(dbTbBusiness.getBusinessId()+"");
        sysNotice.setReceiveUserId(dbTbBusiness.getUserId());
        sysNotice.setReleaseTime(new Date());
        sysNotice.setNoticeTypeClassify(NoticeTypeClassifyEnum.RECHARGE_GOLD.getValue());
        // 极光推送
        Map<String,String> extrasMap = new HashMap<>();
        extrasMap.put("objCode",sysNotice.getObjCode());
        iAsyncService.saveNotice(sysNotice,extrasMap,String.valueOf(sysNotice.getReceiveUserId()));*/
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String iosBeforeBuyVip(AppPayOrderParamBo bo) {
        /*Long userId = SecurityUtils.getUserId();
        SysUser dbSysUser = sysUserMapper.selectById(userId);
        AssertUtils.notNull(dbSysUser,"该用户已不存在");
        Long vipId = bo.getVipId();
        AssertUtils.notNull(vipId,"vipId不能为空");
        TbVip dbTbVip = tbVipMapper.selectById(vipId);
        AssertUtils.notNull(dbTbVip,"该会员信息已被删除");
        AssertUtils.isTrue(dbTbVip.getStatus() != null && dbTbVip.getStatus()==1,"该会员信息已被停用");
        TbBusiness tbBusiness = new TbBusiness();
        tbBusiness.setUserId(userId);
        tbBusiness.setBusinessType("2");
        tbBusiness.setBusinessNumber(IdWorker.getIdStr());
        tbBusiness.setActualTotal(dbTbVip.getVipAmount());
        tbBusiness.setVipId(dbTbVip.getVipId());
        tbBusiness.setVipAmount(dbTbVip.getVipAmount());
        tbBusiness.setVipTitle(dbTbVip.getVipTitle());
        tbBusiness.setVipDay(dbTbVip.getVipDay());
        tbBusiness.setVipValue(dbTbVip.getVipValue());
        tbBusiness.setProductId(dbTbVip.getProductId());
        tbBusiness.setPayStatus(1);
        Date currentDate = new Date();
        tbBusiness.setPayTime(currentDate);
        baseMapper.insert(tbBusiness);*/
        return "";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int iosAfterBuyVip(AppPayOrderParamBo bo) {
        /*LambdaUpdateWrapper<TbBusiness> tbBusinessLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        tbBusinessLambdaUpdateWrapper.eq(TbBusiness::getBusinessNumber, bo.getOrderNumber());
        TbBusiness dbTbBusiness = baseMapper.selectOne(tbBusinessLambdaUpdateWrapper);
        AssertUtils.notNull(dbTbBusiness, "该订单已不存在");
        AssertUtils.isFalse(dbTbBusiness.getPayStatus() != null && dbTbBusiness.getPayStatus() == 2, "该订单已支付");
        // 校验收据码
        this.iosInAppPurchase(dbTbBusiness.getProductId(),bo.getReceipt(), dbTbBusiness);

        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPayStatus, 2);
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPayType,  PayTypeEnum.IOS_PAY.getValue());
        Date currentDate = new Date();
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPayTime, currentDate);
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getReceipt,dbTbBusiness.getReceipt());
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getInTradeNo,dbTbBusiness.getInTradeNo());

        BigDecimal rate = BigDecimal.ZERO;
        BigDecimal zhiRate = BigDecimal.ZERO;
        BigDecimal feiRate = BigDecimal.ZERO;
        BigDecimal pingRate = BigDecimal.ZERO;
        BigDecimal actualTotal = dbTbBusiness.getActualTotal();
        Long userId = dbTbBusiness.getUserId();
        SysUser dbSysUser = sysUserMapper.selectById(userId);
        if (dbSysUser.getZhiUserId() != null) {
            // 分销推荐人
            String value = iSysCommonService.getById(1000070L).getCommonValue();
            BigDecimal rateValue = new BigDecimal(value).divide(new BigDecimal(100));
            zhiRate = actualTotal.multiply(rateValue);
            tbBusinessLambdaUpdateWrapper.set(TbBusiness::getZhiUserId, dbSysUser.getZhiUserId());
            tbBusinessLambdaUpdateWrapper.set(TbBusiness::getZhiRate, zhiRate);
        }
        if (dbSysUser.getBindPartnersStatus() != null && dbSysUser.getBindPartnersStatus() == 1) {
            // 分销绑定办事处
            String value = iSysCommonService.getById(1000071L).getCommonValue();
            BigDecimal rateValue = new BigDecimal(value).divide(new BigDecimal(100));
            feiRate = actualTotal.multiply(rateValue);
            tbBusinessLambdaUpdateWrapper.set(TbBusiness::getFeiUserId, dbSysUser.getBindPartnersId());
            tbBusinessLambdaUpdateWrapper.set(TbBusiness::getFeiRate, feiRate);
        }
        // 平台
        String value = iSysCommonService.getById(1000072L).getCommonValue();
        BigDecimal rateValue = new BigDecimal(value).divide(new BigDecimal(100));
        pingRate = actualTotal.multiply(rateValue);
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getPingRate, pingRate);
        rate = zhiRate.add(feiRate).add(pingRate);
        tbBusinessLambdaUpdateWrapper.set(TbBusiness::getRate, rate);
        int count = baseMapper.update(null, tbBusinessLambdaUpdateWrapper);

        LambdaUpdateWrapper<SysUser> sysUserLambdaUpdateWrapper = new LambdaUpdateWrapper();
        sysUserLambdaUpdateWrapper.eq(SysUser::getUserId, userId);
        sysUserLambdaUpdateWrapper.set(SysUser::getVipStatus, 1);
        Date dueDate = null;
        if (dbSysUser.getVipStatus() != null && dbSysUser.getVipStatus() == 1) {
            dueDate = DateUtils.addDays(dbSysUser.getDueDate(), dbTbBusiness.getVipDay());
            sysUserLambdaUpdateWrapper.set(SysUser::getDueDate, dueDate);
        } else {
            dueDate = DateUtils.addDays(new Date(), dbTbBusiness.getVipDay());
            sysUserLambdaUpdateWrapper.set(SysUser::getDueDate, dueDate);
        }
        sysUserLambdaUpdateWrapper.set(SysUser::getUpdateTime, currentDate);
        sysUserMapper.update(null, sysUserLambdaUpdateWrapper);

        if (dbSysUser != null && dbSysUser.getZhiUserId() != null) {
            TbTrade tbTrade_1 = new TbTrade();
            tbTrade_1.setBusinessId(dbTbBusiness.getBusinessId());
            tbTrade_1.setTradeUserId(dbSysUser.getZhiUserId());
            tbTrade_1.setTradeType(TradeTypeEnum.BUY_MEMBER_IN.getValue());
            tbTrade_1.setTradeAmount(zhiRate);
            tbTrade_1.setTradeTime(currentDate);
            tbTradeMapper.insert(tbTrade_1);
            sysUserMapper.increaseBalanceByUserId(dbSysUser.getZhiUserId(), zhiRate);
        }
        if (dbSysUser.getBindPartnersStatus() != null && dbSysUser.getBindPartnersStatus() == 1) {
            TbTrade tbTrade_1 = new TbTrade();
            tbTrade_1.setBusinessId(dbTbBusiness.getBusinessId());
            tbTrade_1.setTradeUserId(dbSysUser.getBindPartnersId());
            tbTrade_1.setTradeType(TradeTypeEnum.BUY_MEMBER_IN.getValue());
            tbTrade_1.setTradeAmount(feiRate);
            tbTrade_1.setTradeTime(currentDate);
            tbTradeMapper.insert(tbTrade_1);
            sysUserMapper.increaseBalanceByUserId(dbSysUser.getBindPartnersId(), feiRate);
        }
        String redisKey = OrderRedisKeyEnum.VIP_DUE_CANCEL.getValue() + "-" + dbTbBusiness.getUserId() + "-" + dbTbBusiness.getBusinessId();
        // 时间差
        String currentDateStr = DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", new Date());
        String dueDateStr = DateUtils.parseDateToStr("yyyy-MM-dd 23:59:59", dueDate);
        long countDownByTime = DateUtils.getCountDownByTime(DateUtils.stringToDate(currentDateStr, "yyyy-MM-dd HH:mm:ss"), DateUtils.stringToDate(dueDateStr, "yyyy-MM-dd HH:mm:ss"));
        stringRedisTemplate.opsForValue().set(redisKey, dbTbBusiness.getBusinessId() + "", countDownByTime, TimeUnit.SECONDS);
        iTbRedisKeyService.deleteRedisKey(redisKey);
        // 新增redis记录数据
        iTbRedisKeyService.addRedisKey(redisKey, dueDateStr);

        // 推送消息
        SysNotice sysNotice = new SysNotice();
        sysNotice.setNoticeType("2");
        String noticeTitle = NoticeTypeClassifyEnum.BUY_VIP.getDesc();
        sysNotice.setNoticeTitle(noticeTitle);
        String noticeContent = String.format(NoticeTypeClassifyEnum.BUY_VIP.getContent());
        sysNotice.setNoticeContent(noticeContent);
        sysNotice.setStatus("1");
        sysNotice.setObjCode(dbTbBusiness.getBusinessId()+"");
        sysNotice.setReceiveUserId(dbTbBusiness.getUserId());
        sysNotice.setReleaseTime(new Date());
        sysNotice.setNoticeTypeClassify(NoticeTypeClassifyEnum.BUY_VIP.getValue());
        // 极光推送
        Map<String,String> extrasMap = new HashMap<>();
        extrasMap.put("objCode",sysNotice.getObjCode());
        iAsyncService.saveNotice(sysNotice,extrasMap,String.valueOf(sysNotice.getReceiveUserId()));*/
        return 1;
    }

    /**
     * @param productId 产品ID
     * @param receipt   IOS购买凭证
     */
    private void iosInAppPurchase(String productId, String receipt, Object tbBusiness) {
        AssertUtils.notBlank(receipt, "收据码不能为空");
        // type 0 沙盒 非0即线上
        String type = iSysCommonService.getById(1000082L).getCommonValue();
        String verifyResult = IosVerifyUtils.buyAppVerify(receipt, type);
        log.info("IOS内购(充值)=>苹果服务器没有返回验证结果");
        AssertUtils.notBlank(verifyResult, "苹果服务器没有返回验证结果");
        JSONObject job = JSONUtil.parseObj(verifyResult);
        log.info("IOS内购(充值)=>苹果服务器返回验证结果:{}", job);
        String status = job.getStr("status");
        // 是沙盒环境，应沙盒测试，否则执行下面
        if ("21007".equals(status)) {
            verifyResult = IosVerifyUtils.buyAppVerify(receipt, type);
            job = JSONUtil.parseObj(verifyResult);
            status = job.getStr("status");
        }
        if (status.equals("0")) { // 前端所提供的收据是有效的    验证成功
            String r_receipt = job.getStr("receipt");
            JSONObject returnJson = JSONUtil.parseObj(r_receipt);
            String in_app = returnJson.getStr("in_app");
            JSONArray jsonArray = JSONUtil.parseArray(in_app);
            log.info("IOS内购(充值)=>苹果服务器返回验证结果订单数量:{}", jsonArray.size());
            boolean flag = false;
            for (int i = 0; i < jsonArray.size(); i++) {
                String productId_ = jsonArray.getJSONObject(i).get("product_id").toString();
                if (productId.equals(productId_)) {
                    flag = true;
                    break;
                }
            }
            AssertUtils.isTrue(flag, "预支付产品ID与苹果服务器返回产品ID不一致,支付失败");
            String inTradeNo = jsonArray.getJSONObject(0).get("transaction_id").toString();
            // tbBusiness.setReceipt(receipt);
            // tbBusiness.setInTradeNo(inTradeNo);
        } else {
            AssertUtils.isFalse(Boolean.TRUE, "收据凭证是无效的，支付失败");
        }
    }
}